<?php
defined('IN_ZEEGING') or die('Access Denied');
require_once ZEEGING_PATH.'Librarys'.DIRECTORY_SEPARATOR.'ethereum'.DIRECTORY_SEPARATOR.'EthereumApi.php';
require_once ZEEGING_PATH.'Librarys'.DIRECTORY_SEPARATOR.'BOApi.php';
class CliController extends Controller{
	/*
	CREATE TABLE `address` (
	  `merchantid` varchar(50) NOT NULL COMMENT '商户唯一名',
	  `username` varchar(50) NOT NULL COMMENT '商户系统的用户名',
	  `privatekey` varchar(200) NOT NULL COMMENT '私钥',
	  `address` varchar(200) NOT NULL COMMENT '地址',
	  `status` int(11) NOT NULL DEFAULT '0' COMMENT '帐户状态,0为正常状态',
	  `currency` varchar(50) NOT NULL COMMENT '币名称',
	  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
	  PRIMARY KEY (`id`)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='地址和私钥'

	CREATE TABLE `transactions` (
	  `txhash` varchar(200) NOT NULL COMMENT '交易hash',
	  `blockhash` varchar(200) NOT NULL,
	  `blockheight` varchar(50) NOT NULL,
	  `receiveraddress` varchar(200) NOT NULL COMMENT '接受人的地址',
	  `receiverid` varchar(200) NOT NULL COMMENT '接收人的id',
	  `value` varchar(200) NOT NULL COMMENT '交易货币价值',
	  `rmbamount` float NOT NULL COMMENT '交易时等值人民币金额',
	  `currency` varchar(50) NOT NULL COMMENT '币名称',
	  `status` int(4) NOT NULL DEFAULT 0 COMMENT '状态：0初始状态，1充值成功，-1遇到问题',
	  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
	  `time` datetime NOT NULL DEFAULT current_timestamp(),
	  PRIMARY KEY (`id`),
	  UNIQUE KEY `txhash` (`txhash`)
	) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='交易记录'
	*/
	public function mainAction(){
		// print_r($_SERVER);
		$actionName=$_SERVER['argv'][1];
		$methodName=$actionName.'Action';
		if(method_exists($this,$methodName)){
			$this->$methodName();
		}
		else{
			exit('Method '.$methodName.' does not exist.');
		}
	}
	private function depositListenerAction(){
		// 读取数据库里面所有用户
		$accountArray=$this->loadModel('Address')->loadAll('betcat','ETH');
		// 取出读取到的用户地址
		$addressArray=array();
		foreach ($accountArray as $key => $account) {
			array_push($addressArray, $account->address);
		}
		// 实例化ETH交互API
		$api=new EthereumApi();
		// 通过API读取所有相关的交易，这里是执行一个交易过滤操作，返回的是经过过滤的交易，只包含了上面取得的地址里面的交易
		// txFilter函数这里传入了两个参数，实际上还有第三个参数是区块数组，可以传入指定的区块数组让函数按要求过滤，这里没有传则默认是最新的12个区块
		// 这个函数会返回一个对象，结构是 {'blockHeight': xxx, 'txArray':[...]}，blockHeight是当前搜索的最高区块高度
		$txObj=$api->txFilter($addressArray,EthereumApi::FILTER_RECEIVER);
		$depositTxArray=$txObj->txArray;
		$blockHeight=$txObj->blockHeight;
		// 看看有多少个有效的交易
		$availableTxNum=count($depositTxArray);
		// 记录相关日志
		if($availableTxNum>0)
			Base::log("[Blockheight:$blockHeight]DepositListener found $availableTxNum deposit transactions: ".json_encode($depositTxArray));
		else
			Base::log("DepositListening... Currently block height: $blockHeight");
		// 遍历找到的交易，执行每单交易的充值操作
		foreach ($depositTxArray as $key => $tx) {
			$depositOrder=$this->loadModel('DepositOrder');

			$receiverAddress=strtolower($tx->to);

			$address=$this->loadModel('Address')->loadByAddress($receiverAddress,'betcat','ETH');

			$depositOrder->txhash=$tx->hash;
			$depositOrder->blockhash=$tx->blockHash;
			$depositOrder->blockheight=$tx->blockNumber;
			$depositOrder->receiveraddress=$receiverAddress;
			$depositOrder->value=EthereumApi::tx_getValue($tx,'ether');
			$depositOrder->rmbamount=EthereumApi::toFloorFixed(EthereumApi::tx_getValue($tx,'rmb'),2);
			$depositOrder->currency='ETH';
			$depositOrder->receiverid=$address->username;
			// 数据库里设置了txhash字段唯一，意味着同一笔交易不可能生成两次订单，避免重复充值。
			// 这里还不太严谨，没有判断充值状态，最好是判断一下，确保不能有两笔同一txhash的成功交易
			// 不过前期可以接受，如果特殊情况掉单可以人工处理
			if(!$depositOrder->save()){
				Base::log("Found a completed deposit order: username: $depositOrder->receiverid, amount: $depositOrder->rmbamount");
				return;
			}
			Base::log("Created deposit order: id: $depositOrder->id, username: $depositOrder->receiverid, amount: $depositOrder->rmbamount");
			// 找到了交易就掉充值接口充值
			$boapi=new BOApi();
			if($boapi->deposit($depositOrder->receiverid,$depositOrder->rmbamount,BOApi::DEPOSITTYPE_NONWITHDRAWABLE)){
				$depositOrder->success();
				Base::log("Deposit Success: username: $depositOrder->receiverid, amount: $depositOrder->rmbamount");

				// 以下是充值送的逻辑
				$isDepositPromotionEnabling=$this->loadConfigs('base')['DEPOST_PROMOTION'];
				if($isDepositPromotionEnabling){
					try{
						if($depositOrder->rmbamount>=10 && $depositOrder->rmbamount<100){
							$eachMonthAmountList=[3,3,4];
						}
						else if($depositOrder->rmbamount>=100 && $depositOrder->rmbamount<1000){
							$eachMonthAmountList=[10,10,10];
						}
						else if($depositOrder->rmbamount>=1000){
							$eachMonthAmountList=[50,25,25];
						}
						else{
							$eachMonthAmountList=null;
						}
						if(!empty($eachMonthAmountList)){
							// 即时
							$depositNow=$this->loadModel('DepositTask');
							$depositNow->amount=$eachMonthAmountList[1];
							$depositNow->paymentmethod='ethereum';
							$depositNow->username=$depositOrder->receiverid;
							$depositNow->executiondate=date('Y-m-d');
							$depositNow->save();
							$boapi=new BOApi();
							if($boapi->deposit($depositNow->username,$depositNow->amount,BOApi::DEPOSITTYPE_BONUS)){
								$depositNow->success();
								Base::log("A crontask deposit execute success: orderid: $depositNow->id username: $depositNow->username, amount: $depositNow->amount, executiondate: $depositNow->executiondate",'DEPOST_TASK');
							}
							// 次个月
							$depositTaskNextMonth=$this->loadModel('DepositTask');
							$depositTaskNextMonth->amount=$eachMonthAmountList[1];
							$depositTaskNextMonth->paymentmethod='ethereum';
							$depositTaskNextMonth->username=$depositOrder->receiverid;
							$depositTaskNextMonth->executiondate=DepositTaskModel::nextMonth();
							$depositTaskNextMonth->save();
							// 第三个月
							$depositTaskMonthAfterNextMonth=$this->loadModel('DepositTask');
							$depositTaskMonthAfterNextMonth->amount=$eachMonthAmountList[2];
							$depositTaskMonthAfterNextMonth->paymentmethod='ethereum';
							$depositTaskMonthAfterNextMonth->username=$depositOrder->receiverid;
							$depositTaskMonthAfterNextMonth->executiondate=DepositTaskModel::nextMonth(DepositTaskModel::nextMonth());
							$depositTaskMonthAfterNextMonth->save();
						}
						
					}
					catch(Exception $e){
						Base::log("Some error with saving deposit task: order: id: $depositOrder->id, username: $depositOrder->receiverid, amount: $depositOrder->rmbamount, ErrMsg:".$e,'DEPOST_TASK');
					}
				}
				// 充值送逻辑结束
			}
		}
	}
	private function depositTestAction(){
		$tx=json_decode('{
		    "blockHash": "0xc93d90c8b6fbc573df5e685d330b144db428408f23b36090cf7373c231935dff",
		    "blockNumber": "0x4c841f",
		    "from": "0xf5b0a97eec56d779487d030f3a09d304265ddd46",
		    "gas": "0x5208",
		    "gasPrice": "0x12a05f200",
		    "hash": "0xecc67f41d9f2447bb3cfe02ce166928cb4820597c6a29486bcbd7cfe9e0f2343",
		    "input": "0x",
		    "nonce": "0x4",
		    "r": "0xbb2f3ae6bfec28000ac725801a46e3e9b52a0e8736a64904048e0bf20ee74ebc",
		    "s": "0x59a59ece51f26fc2ce14908f36b6d4256347c596fe0d166ddbc7f75157bb1a6c",
		    "to": "0xb6dc3f2129bffd688e34f5e806f5455a591d9502",
		    "transactionIndex": "0x1",
		    "v": "0x29",
		    "value": "0x38d7ea4c68000"
		}');

		$depositOrder=$this->loadModel('DepositOrder');

		$receiverAddress=strtolower($tx->to);

		$address=$this->loadModel('Address')->loadByAddress($receiverAddress,'betcat','ETH');

		$depositOrder->txhash=$tx->hash;
		$depositOrder->blockhash=$tx->blockHash;
		$depositOrder->blockheight=$tx->blockNumber;
		$depositOrder->receiveraddress=$receiverAddress;
		$depositOrder->value=EthereumApi::tx_getValue($tx,'ether');
		$depositOrder->rmbamount=EthereumApi::toFloorFixed(EthereumApi::tx_getValue($tx,'rmb'),2);
		$depositOrder->currency='ETH';
		$depositOrder->receiverid=$address->username;
		$depositOrder->save();
		Base::log("Created deposit order: id: $depositOrder->id, username: $depositOrder->receiverid, amount: $depositOrder->rmbamount");

		$boapi=new BOApi();
		if($boapi->deposit($depositOrder->receiverid,$depositOrder->rmbamount,BOApi::DEPOSITTYPE_NONWITHDRAWABLE)){
			$depositOrder->success();
			Base::log("Deposit Success: username: $depositOrder->receiverid, amount: $depositOrder->rmbamount");
		}
	}
	public function testAction(){
		// $api=new EthereumApi();
		// $newAddress=$api->generateWallet();
		// print_r(json_encode($newAddress));
		$isDepositPromotionEnabling=$this->loadConfigs('base')['DEPOST_PROMOTION'];
		print_r($isDepositPromotionEnabling);
		try{
			$depositTaskNextMonth=$this->loadModel('DepositTask');
			$depositTaskNextMonth->amount='100';
			$depositTaskNextMonth->paymentmethod='ethereum';
			$depositTaskNextMonth->username='17665343247';
			$depositTaskNextMonth->executiondate=DepositTaskModel::nextMonth();
			$depositTaskNextMonth->save();

			$depositTaskMonthAfterNextMonth=$this->loadModel('DepositTask');
			$depositTaskMonthAfterNextMonth->amount='100';
			$depositTaskMonthAfterNextMonth->paymentmethod='ethereum';
			$depositTaskMonthAfterNextMonth->username='17665343247';
			$depositTaskMonthAfterNextMonth->executiondate=DepositTaskModel::nextMonth(DepositTaskModel::nextMonth());
			$depositTaskMonthAfterNextMonth->save();
		}
		catch(Exception $e){
			print_r($e);
		}
		
	}
	// 执行充值送任务定时脚本
	public function executeDepositAction(){
		$depositTaskList=$this->loadModel('DepositTask')->loadAllTasksShouldBeExecutedToday();
		$boapi=new BOApi();
		foreach ($depositTaskList as $key => $task) {
			if($boapi->deposit($task->username,$task->amount,BOApi::DEPOSITTYPE_BONUS)){
				$order=$this->loadModel('DepositTask')->load($task->id);
				$order->success();
				Base::log("A crontask deposit execute success: orderid: $task->id username: $task->username, amount: $task->amount, executiondate: $task->executiondate",'DEPOST_TASK');
			}
		}
	}
}
//------------------------------------------------
//End of File : /Controllers/IndexController.class.php
//------------------------------------------------
